package com.mzj.saas.mservice.smartlock.service.tianwanghulian;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.json.JSONObject;
import com.alibaba.fastjson.JSON;
import com.haixiaoke.saas.repository.util.GsonUtil;
import com.mzj.saas.commons.ResultBean;
import com.mzj.saas.commons.StatusCode;
import com.mzj.saas.mservice.lock.Repository.*;
import com.mzj.saas.mservice.lock.entity.*;
import com.mzj.saas.mservice.smartlock.base.BaseLock;
import com.mzj.saas.mservice.smartlock.vo.SmartLockFingerprintVO;
import com.mzj.saas.mservice.smartlock.vo.SmartLockVO;
import com.mzj.saas.redis.RedisService;
import org.apache.commons.lang3.RandomUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * 天网互联-智能锁接口
 */
@Service
public class SmartLockTWHlService implements BaseLock {

    @Autowired
    private RedisService redisService;
    @Autowired
    private SmartLockRepository smartLockRepository;
    @Autowired
    private SmartLockAuthRepository smartLockAuthRepository;
    @Value("${tianwanghulian.lock.callback.url}")
    private String tianWangHuLianCallbackUrl;
    @Autowired
    private SmartLockPwdRepository smartLockPwdRepository;
    @Autowired
    private JdbcTemplate jdbcTemplate;
    @Autowired
    private SmartLockCardRepository smartLockCardRepository;
    @Autowired
    private SmartLockFingerprintRepository smartLockFingerprintRepository;
    @Autowired
    private SmartLockBleRepository smartLockBleRepository;

    /**
     * 授权密码和授权临时密码
     *
     * @return
     */
    @Override
    public ResultBean<String> authorizationPwd(SmartLockVO vo, SmartLockPwd smartLockPwd) {
        Integer type = smartLockPwd.getType();
        Integer authType = smartLockPwd.getAuthType();
        Map<String, Object> hashMap = new HashMap<String, Object>();
        String token = redisService.getToken();
        if (type == SmartLockPwd.LOCK_TYPE_CUSTOM || type == SmartLockPwd.LOCK_TYPE_GENERATE) {
            //授权密码和授权临时密码
            if (authType == 1 || authType == 2) {
                String startTime = DateUtil.formatDateTime(smartLockPwd.getStartTime());
                String endTime = DateUtil.formatDateTime(smartLockPwd.getEndTime());
                hashMap.put("deviceNum", vo.getSn());
                hashMap.put("identification", vo.getIdentification());
                hashMap.put("password", vo.getPassword());
                hashMap.put("startTime", startTime);
                hashMap.put("endTime", endTime);
                String s = HttpRequest.post(tianWangHuLianCallbackUrl + "/api/temporarySinglePassword.do")
                        .header("Authorization", token)//头信息，多个头信息多次调用此方法即可
                        .body(GsonUtil.toJson(hashMap))
                        .timeout(20000)//超时，毫秒
                        .execute().body();
                ResultBean<String> objectResultBean = getStringResultBean(s);
                if (objectResultBean != null) return objectResultBean;
                return ResultBean.successfulResult(JSON.toJSONString(s));
            }
            ResultBean<String> objectResultBean = new ResultBean<>();
            objectResultBean.setMsg("无次数密码");
            objectResultBean.setCode(StatusCode.ERROR_CODE_10001.getErrorCode());
            return objectResultBean;
        }
        if (Objects.equals(type, SmartLockPwd.LOCK_TYPE_GENERATE_TEMPORARY)) {
            //授权密码和授权临时密码
            if (authType == 1 || authType == 2) {
                String startTime = DateUtil.formatDateTime(smartLockPwd.getStartTime());
                String endTime = DateUtil.formatDateTime(smartLockPwd.getEndTime());
                hashMap.put("deviceNum", vo.getSn());
                hashMap.put("identification", vo.getIdentification());
                hashMap.put("password", vo.getPassword());
                hashMap.put("startTime", startTime);
                hashMap.put("endTime", endTime);
                String s = HttpRequest.post(tianWangHuLianCallbackUrl + "/api/temporarySinglePassword.do")
                        .header("Authorization", token)//头信息，多个头信息多次调用此方法即可
                        .body(GsonUtil.toJson(hashMap))
                        .timeout(20000)//超时，毫秒
                        .execute().body();
                ResultBean<String> objectResultBean = getStringResultBean(s);
                if (objectResultBean != null) return objectResultBean;
                return ResultBean.successfulResult(JSON.toJSONString(s));
            }
            ResultBean<String> objectResultBean = new ResultBean<>();
            objectResultBean.setMsg("无次数密码");
            objectResultBean.setCode(StatusCode.ERROR_CODE_10001.getErrorCode());
            return objectResultBean;
        }
        return ResultBean.failedResult("密码生成方式错误");

    }

    /**
     * 删除密码授权
     *
     * @param vo
     * @return
     */
    @Override
    public ResultBean<String> deletePwd(SmartLockVO vo, Long lockAuthId) {
        Map<String, Object> hashMap = new HashMap<String, Object>();
        String sql = "SELECT * FROM saas_smart_lock_pwd WHERE lock_auth_id = ? and (type = 1 or type = 2)";
        SmartLockPwd byLockAuthId = jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper<>(SmartLockPwd.class), vo.getAuthInfoId());
        //判断授权密码是否已经过期，如果过期直接返回成功
        Date endTime = byLockAuthId.getEndTime();
        DateTime date = DateUtil.date();
        //结束时间比当前时间早
        boolean before = endTime.before(date);
        if (before) {
            return ResultBean.successfulResult("成功");
        }
        //天网互联密码标识
        String identification = byLockAuthId.getIdentification();
        String token = redisService.getToken();
        hashMap.put("deviceNum", vo.getSn());
        hashMap.put("identification", identification);
        String s = HttpRequest.delete(tianWangHuLianCallbackUrl + "/api/temporarySinglePassword.do")
                .header("Authorization", token)//头信息，多个头信息多次调用此方法即可
                .body(GsonUtil.toJson(hashMap))
                .timeout(20000)//超时，毫秒
                .execute().body();
        ResultBean<String> objectResultBean = getStringResultBean(s);
        if (objectResultBean != null) return objectResultBean;
        return ResultBean.successfulResult(JSON.toJSONString(s));
    }

    /**
     * 授权指纹开锁
     * @param vo
     * @return
     */
    @Override
    public ResultBean<String> fingerprintUnlocking(SmartLockFingerprintVO vo) {
        String authType = vo.getAuthType();
        Map<String, Object> hashMap = new HashMap<String, Object>();
        Map<String, Object> map = new HashMap<String, Object>();
        String token = redisService.getToken();
        //添加指纹数据
        if (authType.equals("1")) {
            hashMap.put("deviceNum", vo.getSn());
            hashMap.put("identification", vo.getIdentification());
            hashMap.put("fingerprintData", vo.getFingerprint());
            String s = HttpRequest.post(tianWangHuLianCallbackUrl + "/api/saveFingerprintInfo.do")
                    .header("Authorization", token)//头信息，多个头信息多次调用此方法即可
                    .body(GsonUtil.toJson(hashMap))
                    .timeout(20000)//超时，毫秒
                    .execute().body();
            ResultBean<String> objectResultBean = getStringResultBean(s);
            if (objectResultBean != null) return objectResultBean;
            //下发指纹数据
            map.put("deviceNum", vo.getSn());
            map.put("identification", vo.getIdentification());
            String result = HttpRequest.post(tianWangHuLianCallbackUrl + "/api/sendFingerprintData.do")
                    .header("Authorization", token)//头信息，多个头信息多次调用此方法即可
                    .body(GsonUtil.toJson(map))
                    .timeout(20000)//超时，毫秒
                    .execute().body();
            ResultBean<String> resultBean = getStringResultBean(result);
            if (resultBean != null) return resultBean;
            return ResultBean.successfulResult(JSON.toJSONString(result));
        }
        ResultBean<String> objectResultBean = new ResultBean<>();
        objectResultBean.setMsg("无时限指纹授权");
        objectResultBean.setCode(StatusCode.ERROR_CODE_10001.getErrorCode());
        return objectResultBean;

    }

    /**
     * 删除指纹开锁
     * @param vo
     * @return
     */
    @Override
    public ResultBean<String> deleteFingerprintUnlocking(SmartLockVO vo) {
        Map<String, Object> hashMap = new HashMap<String, Object>();
        String token = redisService.getToken();
        hashMap.put("deviceNum", vo.getSn());
        hashMap.put("identification", vo.getIdentification());
        List<SmartLockFingerprint> smartLockFingerprintList = smartLockFingerprintRepository.findByLockAuthId(vo.getAuthInfoId());
        //判断授权指纹是否已经过期，如果过期直接返回成功
        Date endTime = smartLockFingerprintList.get(0).getEndTime();
        DateTime date = DateUtil.date();
        //结束时间比当前时间早
        boolean before = endTime.before(date);
        if (before) {
            return ResultBean.successfulResult("成功");
        }
        String s = HttpRequest.delete(tianWangHuLianCallbackUrl + "/api/deleteFingerprintInfo.do")
                .header("Authorization", token)//头信息，多个头信息多次调用此方法即可
                .body(GsonUtil.toJson(hashMap))
                .timeout(20000)//超时，毫秒
                .execute().body();
        ResultBean<String> objectResultBean = getStringResultBean(s);
        if (objectResultBean != null) return objectResultBean;
        return ResultBean.successfulResult(JSON.toJSONString(s));
    }

    @Override
    public boolean doorCardUnlocking() {
        return false;
    }

    /**
     * 授权身份证/CUP卡开锁
     *
     * @return
     */
    @Override
    public ResultBean<String> identityCardUnlocking(SmartLockVO vo, SmartLockCard smartLockCard) {
        Map<String, Object> hashMap = new HashMap<String, Object>();
        String token = redisService.getToken();
        //授权身份证/授权CPU卡
        String startTime = DateUtil.formatDateTime(smartLockCard.getStartTime());
        String endTime = DateUtil.formatDateTime(smartLockCard.getEndTime());
        Integer type = smartLockCard.getType();//1:授权身份证 2：授权CUP卡
        hashMap.put("deviceNum", vo.getSn());
        hashMap.put("identification", vo.getIdentification());
        hashMap.put("startTime", startTime);
        hashMap.put("endTime", endTime);
        //1:授权身份证 2：授权CUP卡
        if (type == 1) {
            //四代授权身份证需要传16位16进制的数据；
            String cardNum = String.format("%16X", Long.valueOf(smartLockCard.getCardNumber()));
            hashMap.put("cardType", 1);
            hashMap.put("cardNum", cardNum);
            String s = HttpRequest.post(tianWangHuLianCallbackUrl + "/api/singleIdentity.do")
                    .header("Authorization", token)//头信息，多个头信息多次调用此方法即可
                    .body(GsonUtil.toJson(hashMap))
                    .timeout(20000)//超时，毫秒
                    .execute().body();
            ResultBean<String> objectResultBean = getStringResultBean(s);
            if (objectResultBean != null) return objectResultBean;
            return ResultBean.successfulResult(JSON.toJSONString(s));
        }
        if (type == 2) {
            //四代授权CPU卡需要传8位16进制的数据；
            //String cardNum = String.format("%08X", Long.valueOf(smartLockCard.getCardNumber()));
            hashMap.put("cardType", 0);
            hashMap.put("cardNum", smartLockCard.getCardId());
            String s = HttpRequest.post(tianWangHuLianCallbackUrl + "/api/singleCard.do")
                    .header("Authorization", token)//头信息，多个头信息多次调用此方法即可
                    .body(GsonUtil.toJson(hashMap))
                    .timeout(20000)//超时，毫秒
                    .execute().body();
            ResultBean<String> objectResultBean = getStringResultBean(s);
            if (objectResultBean != null) return objectResultBean;
            return ResultBean.successfulResult(JSON.toJSONString(s));
        }
        return ResultBean.failedResult("无该授权卡类型");
    }

    /**
     * 删除身份证/CUP卡开锁
     *
     * @return
     */
    @Override
    public ResultBean<String> deleteIdentityCardUnlocking(SmartLockVO vo) {
        Map<String, Object> hashMap = new HashMap<String, Object>();
        String token = redisService.getToken();
        SmartLockCard byLockAuthIdAndType = smartLockCardRepository.findByLockAuthIdAndType(vo.getAuthInfoId(), vo.getCardType());
        //判断授权门卡是否已经过期，如果过期直接返回成功
        Date endTime = byLockAuthIdAndType.getEndTime();
        DateTime date = DateUtil.date();
        //结束时间比当前时间早
        boolean before = endTime.before(date);
        if (before) {
            return ResultBean.successfulResult("成功");
        }
        //天网互联密码标识
        String identification = byLockAuthIdAndType.getIdentification();
        hashMap.put("deviceNum", vo.getSn());
        hashMap.put("identification", identification);
        String s = HttpRequest.delete(tianWangHuLianCallbackUrl + "/api/singleCard.do")
                .header("Authorization", token)//头信息，多个头信息多次调用此方法即可
                .body(GsonUtil.toJson(hashMap))
                .timeout(20000)//超时，毫秒
                .execute().body();
        ResultBean<String> objectResultBean = getStringResultBean(s);
        if (objectResultBean != null) return objectResultBean;
        return ResultBean.successfulResult(JSON.toJSONString(s));
    }

    /**
     * 授权蓝牙开锁
     *
     * @return
     */
    @Override
    public ResultBean<String> bluetoothUnlocking(SmartLockVO vo, SmartLockBle smartLockBle) {
        Map<String, Object> hashMap = new HashMap<String, Object>();
        Map<String, Object> map = new HashMap<String, Object>();
        List<Object> passwordList = new ArrayList<>();
        String token = redisService.getToken();
        String startTime = DateUtil.formatDateTime(smartLockBle.getStartTime());
        String endTime = DateUtil.formatDateTime(smartLockBle.getEndTime());
        map.put("identification", vo.getIdentification());
        map.put("startTime", startTime);
        map.put("endTime", endTime);
        passwordList.add(map);
        hashMap.put("deviceNum", vo.getSn());
        hashMap.put("passwordList", passwordList);
        String s = HttpRequest.post(tianWangHuLianCallbackUrl + "/api/bluetooth/unlockAuthority.do")
                .header("Authorization", token)//头信息，多个头信息多次调用此方法即可
                .body(GsonUtil.toJson(hashMap))
                .timeout(20000)//超时，毫秒
                .execute().body();
        ResultBean<String> objectResultBean = getStringResultBean(s);
        if (objectResultBean != null) return objectResultBean;
        return ResultBean.successfulResult(JSON.toJSONString(s));
    }

    /**
     * 获取蓝牙密钥
     *
     * @return
     */
    @Override
    public ResultBean<String> getBluetoothUnlocking(Long lockAuthId) {
        Map<String, Object> hashMap = new HashMap<String, Object>();
        String token = redisService.getToken();
        SmartLockBle byLockAuthId = smartLockBleRepository.findByLockAuthId(lockAuthId);
        //天网互联密码标识
        String identification = byLockAuthId.getIdentification();
        String mac = smartLockAuthRepository.BluetoothKey(lockAuthId);
        hashMap.put("identification", identification);
        hashMap.put("deviceNum", mac);
        String s = HttpRequest.get(tianWangHuLianCallbackUrl + "/api/bluetooth/unlockKey.do")
                .header("Authorization", token)//头信息，多个头信息多次调用此方法即可
                .form(hashMap)
                .timeout(20000)//超时，毫秒
                .execute().body();
        ResultBean<String> objectResultBean = getStringResultBean(s);
        if (objectResultBean != null) return objectResultBean;
        return ResultBean.successfulResult(s);
    }

    /**
     * 删除蓝牙开锁权限
     *
     * @return
     */
    @Override
    public ResultBean<String> deleteBluetoothUnlocking(SmartLockVO vo) {
        Map<String, Object> hashMap = new HashMap<String, Object>();
        List<Object> identifications = new ArrayList<>();
        String token = redisService.getToken();
        Long lockAuthId = vo.getAuthInfoId();
        SmartLockBle byLockAuthId = smartLockBleRepository.findByLockAuthId(lockAuthId);
        //判断授权蓝牙是否已经过期，如果过期直接返回成功
        Date endTime = byLockAuthId.getEndTime();
        DateTime date = DateUtil.date();
        //结束时间比当前时间早
        boolean before = endTime.before(date);
        if (before) {
            return ResultBean.successfulResult("成功");
        }
        //天网互联密码标识
        String identification = byLockAuthId.getIdentification();
        identifications.add(identification);
        hashMap.put("deviceNum", vo.getSn());
        hashMap.put("identifications", identifications);
        String s = HttpRequest.delete(tianWangHuLianCallbackUrl + "/api/bluetooth/unlockAuthority.do")
                .header("Authorization", token)//头信息，多个头信息多次调用此方法即可
                .body(GsonUtil.toJson(hashMap))
                .timeout(20000)//超时，毫秒
                .execute().body();
        ResultBean<String> objectResultBean = getStringResultBean(s);
        if (objectResultBean != null) return objectResultBean;
        return ResultBean.successfulResult(JSON.toJSONString(s));
    }

    /**
     * 删除智能锁所有授权
     * @param mac
     * @param lockId
     * @return
     */
    @Override
    public ResultBean<String> deleteAll(String mac, Long lockId) {
        String token = redisService.getToken();
        //删除所有授权密码
        List<SmartLockPwd> smartLockPwdList = smartLockPwdRepository.findByLockId(lockId);
        if (CollectionUtil.isNotEmpty(smartLockPwdList)) {
            Map<String, Object> map = new HashMap<String, Object>();
            List<String> list= new ArrayList<>();
            //smartLockPwdList.forEach(smartLockPwd -> {
            //    list.add(smartLockPwd.getIdentification());
            //});
            for (SmartLockPwd smartLockPwd : smartLockPwdList) {
                //判断授权密码是否已经过期，如果过期直接返回成功
                Date endTime = smartLockPwd.getEndTime();
                DateTime date = DateUtil.date();
                //结束时间比当前时间晚
                boolean before = endTime.after(date);
                if (before) {
                    list.add(smartLockPwd.getIdentification());
                }
            }
           if (CollectionUtil.isNotEmpty(list)) {
               map.put("deviceNum",mac);
               map.put("identifications",list);
               String s = HttpRequest.delete(tianWangHuLianCallbackUrl + "/api/temporaryPassword.do")
                       .header("Authorization", token)//头信息，多个头信息多次调用此方法即可
                       .body(GsonUtil.toJson(map))
                       .timeout(20000)//超时，毫秒
                       .execute().body();
               ResultBean<String> objectResultBean = getStringResultBean(s);
               if (objectResultBean != null) return objectResultBean;
           }
        }
        //删除所有指纹
        List<SmartLockFingerprint> smartLockFingerprintList = smartLockFingerprintRepository.findByLockId(lockId);
        if (CollectionUtil.isNotEmpty(smartLockFingerprintList)) {
            for (SmartLockFingerprint smartLockFingerprint : smartLockFingerprintList) {
                //判断授权指纹是否已经过期，如果过期直接返回成功
                Date endTime = smartLockFingerprint.getEndTime();
                DateTime date = DateUtil.date();
                //结束时间比当前时间晚
                boolean before = endTime.after(date);
                if (before) {
                    Map<String, Object> map = new HashMap<String, Object>();
                    map.put("deviceNum",mac);
                    map.put("identification",smartLockFingerprint.getIdentification());
                    String s = HttpRequest.delete(tianWangHuLianCallbackUrl + "/api/deleteFingerprintInfo.do")
                            .header("Authorization", token)//头信息，多个头信息多次调用此方法即可
                            .body(GsonUtil.toJson(map))
                            .timeout(20000)//超时，毫秒
                            .execute().body();
                    ResultBean<String> objectResultBean = getStringResultBean(s);
                    if (objectResultBean != null) return objectResultBean;
                }
            }
        }
        //删除所有身份证和CPU卡
        List<SmartLockCard> smartLockCardList = smartLockCardRepository.findByLockId(lockId);
        if (CollectionUtil.isNotEmpty(smartLockCardList)) {
            Map<String, Object> map = new HashMap<String, Object>();
            List<String> list= new ArrayList<>();
            //smartLockCardList.forEach(smartLockCard -> {
            //    list.add(smartLockCard.getIdentification());
            //});
            for (SmartLockCard smartLockCard : smartLockCardList) {
                //判断授权门卡是否已经过期，如果过期直接返回成功
                Date endTime = smartLockCard.getEndTime();
                DateTime date = DateUtil.date();
                //结束时间比当前时间晚
                boolean before = endTime.after(date);
                if (before) {
                    list.add(smartLockCard.getIdentification());
                }
            }
           if (CollectionUtil.isNotEmpty(list)) {
               map.put("deviceNum",mac);
               map.put("identifications",list);
               String s = HttpRequest.delete(tianWangHuLianCallbackUrl + "/api/cardInfo.do")
                       .header("Authorization", token)//头信息，多个头信息多次调用此方法即可
                       .body(GsonUtil.toJson(map))
                       .timeout(20000)//超时，毫秒
                       .execute().body();
               ResultBean<String> objectResultBean = getStringResultBean(s);
               if (objectResultBean != null) return objectResultBean;
           }
        }
        //删除所有蓝牙
        List<SmartLockBle> smartLockBleList = smartLockBleRepository.findByLockId(lockId);
        if (CollectionUtil.isNotEmpty(smartLockBleList)) {
            Map<String, Object> map = new HashMap<String, Object>();
            List<String> list= new ArrayList<>();
            //smartLockBleList.forEach(smartLockBle -> {
            //    list.add(smartLockBle.getIdentification());
            //});
            for (SmartLockBle smartLockBle : smartLockBleList) {
                //判断授权蓝牙是否已经过期，如果过期直接返回成功
                Date endTime = smartLockBle.getEndTime();
                DateTime date = DateUtil.date();
                //结束时间比当前时间晚
                boolean before = endTime.after(date);
                if (before) {
                    list.add(smartLockBle.getIdentification());
                }
            }
           if (CollectionUtil.isNotEmpty(list)) {
               map.put("deviceNum",mac);
               map.put("identifications",list);
               String s = HttpRequest.delete(tianWangHuLianCallbackUrl + "/api/bluetooth/unlockAuthority.do")
                       .header("Authorization", token)//头信息，多个头信息多次调用此方法即可
                       .body(GsonUtil.toJson(map))
                       .timeout(20000)//超时，毫秒
                       .execute().body();
               ResultBean<String> objectResultBean = getStringResultBean(s);
               if (objectResultBean != null) return objectResultBean;
           }
        }
        return ResultBean.successfulResult("删除成功");
    }

    private ResultBean<String> getStringResultBean(String s) {
        JSONObject jsonObject = new JSONObject(s);
        Integer code = (Integer) jsonObject.get("code");
        if (code != 0) {
            ResultBean<String> objectResultBean = new ResultBean<>();
            objectResultBean.setMsg((String) jsonObject.get("msg"));
            objectResultBean.setCode(StatusCode.ERROR_CODE_10001.getErrorCode());
            return objectResultBean;
        }
        return null;
    }
}
